<template>
  <div class="dashboard-page command-map-page">
    <div class="header-bar">
      <h1 class="page-title">克拉玛依指挥地图</h1>
      <div class="map-controls">
        <button class="btn btn-secondary" @click="handleRefresh">刷新地图</button>
        <button class="btn btn-primary" @click="handleZoomIn">放大</button>
        <button class="btn btn-primary" @click="handleZoomOut">缩小</button>
      </div>
    </div>

    <div class="map-wrapper">
      <div v-if="isLoading" class="loading-overlay">
        <div class="loading-spinner"></div>
      </div>
      <div v-else-if="mapError" class="error-message">
        {{ mapError }}
      </div>
      <MapContainer
        v-else
        ref="mapRef"
        :officers="officerData"
        :incidents="incidentData"
        :key="mapKey"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import MapContainer from './MapContainer.vue';
import api from '@/utils/axios';

// 高德地图API密钥
const API_KEY = 'e67f0e9520643f148baa0e9747a27038';

// 组件状态
const mapRef = ref<InstanceType<typeof MapContainer> | null>(null);
const isLoading = ref(true);
const mapKey = ref(Date.now());
const mapError = ref<string | null>(null);

// 数据存储
const officerData = ref<any[]>([]);
const incidentData = ref<any[]>([]);

// 克拉玛依的经纬度范围
const 克拉玛依经纬度范围 = {
  lng: { min: 84.812456, max: 87.731148 },
  lat: { min: 45.543682, max: 46.062955 }
};

// 生成随机经纬度
const generateRandomCoordinates = () => {
  const randomLng = 克拉玛依经纬度范围.lng.min + Math.random() * (克拉玛依经纬度范围.lng.max - 克拉玛依经纬度范围.lng.min);
  const randomLat = 克拉玛依经纬度范围.lat.min + Math.random() * (克拉玛依经纬度范围.lat.max - 克拉玛依经纬度范围.lat.min);
  return { lng: randomLng, lat: randomLat };
};

// 逆地理编码：使用RESTful API将经纬度转换为地址
const geocodeLocation = async (lng: number, lat: number): Promise<string> => {
  try {
    // 构建REST API请求URL
    const url = `https://restapi.amap.com/v3/geocode/regeo?key=${API_KEY}&location=${lng},${lat}&extensions=base&output=JSON`;

    // 发送请求
    const response = await fetch(url);
    const data = await response.json();

    // 检查响应状态
    if (data.status === '1' && data.info === 'OK') {
      return data.regeocode.formatted_address || '未知地址';
    } else {
      console.warn('逆地理编码失败:', data.info);
      return '无法获取地址信息';
    }
  } catch (error) {
    console.error('逆地理编码异常:', error);
    return '获取地址信息时发生错误';
  }
};

// 获取警员数据
const fetchOfficers = async () => {
  try {
    const response = await api.get('/officers');
    const list = response.data?.data || [];

    officerData.value = list.map((officer: any) => {
      let lng, lat;
      if (officer.longitude && officer.latitude) {
        lng = parseFloat(officer.longitude);
        lat = parseFloat(officer.latitude);
      } else {
        const randomCoords = generateRandomCoordinates();
        lng = randomCoords.lng;
        lat = randomCoords.lat;
      }
      return {
        id: officer.id,
        name: officer.name || '未知',
        statusDescription: officer.statusDescription || '未知',
        lng,
        lat
      };
    });
  } catch (error) {
    console.error('获取警员数据失败:', error);
    officerData.value = [];
    mapError.value = '警员数据加载失败';
  }
};

// 获取事件数据并进行逆地理编码
const fetchIncidents = async () => {
  try {
    const response = await api.get('/incidents');
    const list = response.data || [];

    const incidentsWithAddress = [];

    // 先加载所有事件基本数据
    for (const incident of list) {
      try {
        const lng = incident.coordinates[0];
        const lat = incident.coordinates[1];
        const type = incident.incidentType;

        incidentsWithAddress.push({
          id: incident.incidentId,
          title: incident.incidentType || '未知事件',
          lng,
          lat,
          type,
          address: '获取地址中...' // 先占位，后面替换
        });
      } catch (error) {
        console.error('处理事件数据失败:', error);
      }
    }

    // 更新界面显示基本数据
    incidentData.value = [...incidentsWithAddress];

    // 批量处理地理编码
    const batchSize = 5;
    let processed = 0;

    while (processed < incidentsWithAddress.length) {
      // 每批处理batchSize个地址
      const batch = incidentsWithAddress.slice(processed, processed + batchSize);

      // 并行获取地址信息
      const results = await Promise.all(
        batch.map(incident =>
          geocodeLocation(incident.lng, incident.lat)
        )
      );
      console.log(results)

      // 更新地址信息
      results.forEach((address, index) => {
        incidentsWithAddress[processed + index].address = address;
      });

      // 更新显示数据，触发重新渲染
      incidentData.value = [...incidentsWithAddress];

      processed += batchSize;

      // 增加间隔防止请求过快
      await new Promise(resolve => setTimeout(resolve, 300));
    }
  } catch (error) {
    console.error('获取事件数据失败:', error);
    incidentData.value = [];
    mapError.value = '事件数据加载失败';
  }
};

// 加载所有数据
const loadData = async () => {
  isLoading.value = true;
  mapError.value = null;

  try {
    await Promise.all([
      fetchOfficers(),
      fetchIncidents()
    ]);
  } catch (error: any) {
    mapError.value = error.message || '数据加载失败';
    console.error('加载数据失败:', error);
  } finally {
    isLoading.value = false;
    mapKey.value = Date.now(); // 重新渲染地图组件
  }
};

// 处理刷新按钮点击事件
const handleRefresh = () => {
  loadData();
};

// 处理放大按钮点击事件
const handleZoomIn = () => {
  if (mapRef.value) {
    mapRef.value.zoomIn();
  }
};

// 处理缩小按钮点击事件
const handleZoomOut = () => {
  if (mapRef.value) {
    mapRef.value.zoomOut();
  }
};

// 组件挂载时初始化
onMounted(() => {
  loadData();
});

// 组件卸载时清理
onUnmounted(() => {
  if (mapRef.value) {
    mapRef.value.destroy();
  }
});
</script>

<style scoped>
@import "@/assets/styles/views/dashboard/CommandMap.css";

.dashboard-page.command-map-page {
  display: flex;
  flex-direction: column;
  height: 100%;
  background-color: #f5f7fa;
  padding: 20px;
}

.header-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 15px 25px;
  background-color: #fff;
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.page-title {
  color: #2c3e50;
  font-size: 1.8rem;
  font-weight: 600;
  margin: 0;
}

.map-controls {
  display: flex;
  gap: 12px;
}

.btn {
  padding: 10px 20px;
  border-radius: 6px;
  font-weight: 500;
  font-size: 0.95rem;
  cursor: pointer;
  transition: all 0.3s ease;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
}

.btn-primary {
  background-color: #409eff;
  color: white;
}

.btn-primary:hover {
  background-color: #337ecc;
  transform: translateY(-2px);
}

.btn-secondary {
  background-color: #f5f7fa;
  color: #606266;
  border: 1px solid #dcdfe6;
}

.btn-secondary:hover {
  background-color: #ecf5ff;
  color: #409eff;
  border-color: #c6e2ff;
}

.map-wrapper {
  position: relative;
  flex: 1;
  border-radius: 12px;
  overflow: hidden;
  background-color: white;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.8);
  z-index: 10;
}

.loading-spinner {
  width: 50px;
  height: 50px;
  border: 5px solid rgba(52, 152, 219, 0.2);
  border-top: 5px solid #3498db;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.error-message {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #e74c3c;
  font-size: 18px;
  padding: 20px;
  text-align: center;
  border: 1px solid #ffcfcf;
  border-radius: 8px;
  background-color: #fffafa;
  margin: 20px;
  box-shadow: 0 2px 8px rgba(231, 76, 60, 0.15);
  z-index: 10;
}

@media (max-width: 768px) {
  .header-bar {
    flex-direction: column;
    align-items: flex-start;
    padding: 15px;
  }

  .map-controls {
    margin-top: 15px;
    width: 100%;
    justify-content: flex-end;
  }

  .page-title {
    font-size: 1.5rem;
  }
}
</style>
